vcpu_iodata_t *vio;
ioreq_t *p;
+ if (size == 0 || count == 0) {
+ printf("null pio request? port %lx, count %lx, size %d, value %lx, dir %d, pvalid %d.\n",
+ port, count, size, value, dir, pvalid);
+ }
+
vio = get_vio(v->domain, v->vcpu_id);
if (vio == NULL) {
printk("bad shared page: %lx\n", (unsigned long) vio);
hvm_send_assist_req(v);
}
-void send_mmio_req(
+static void send_mmio_req(
unsigned char type, unsigned long gpa,
unsigned long count, int size, long value, int dir, int pvalid)
{
ioreq_t *p;
struct cpu_user_regs *regs;
+ if (size == 0 || count == 0) {
+ printf("null mmio request? type %d, gpa %lx, count %lx, size %d, value %lx, dir %d, pvalid %d.\n",
+ type, gpa, count, size, value, dir, pvalid);
+ }
+
regs = ¤t->arch.hvm_vcpu.io_op.io_context;
vio = get_vio(v->domain, v->vcpu_id);
unsigned long addr = 0;
int dir;
+ ASSERT(count);
+
/* determine non-MMIO address */
if (realmode) {
if (((regs->es << 4) + (regs->edi & 0xFFFF)) == va) {
mmio_opp->flags = mmio_inst.flags;
mmio_opp->instr = mmio_inst.instr;
+ if (addr & (size - 1))
+ DPRINTK("Unaligned ioport access: %lx, %ld\n", addr, size);
+
/*
* In case of a movs spanning multiple pages, we break the accesses
* up into multiple pages (the device model works with non-continguous
if ((addr & PAGE_MASK) != ((addr + sign * (size - 1)) & PAGE_MASK)) {
unsigned long value = 0;
+ DPRINTK("Single io request in a movs crossing page boundary.\n");
mmio_opp->flags |= OVERLAP;
regs->eip -= inst_len; /* do not advance %eip */
if ((addr & PAGE_MASK) != ((addr + sign * (count * size - 1)) & PAGE_MASK)) {
regs->eip -= inst_len; /* do not advance %eip */
- if (sign > 0)
+ if (sign > 0) {
count = (PAGE_SIZE - (addr & ~PAGE_MASK)) / size;
- else
- count = (addr & ~PAGE_MASK) / size;
+ } else {
+ /* We need to make sure we advance to the point
+ where the next request will be on a different
+ page. If we're going down, that means
+ advancing until one byte before the start of
+ the page, hence +1. */
+ count = ((addr + 1) & ~PAGE_MASK) / size;
+ }
}
+ ASSERT(count);
send_mmio_req(IOREQ_TYPE_COPY, gpa, count, size, addr, dir, 1);
}
break;